/*
 * @Author: aleimu
 * @Date: 2021-03-08 09:36:50
 * @Description: 复杂的 Form 提交方式,应该够用了吧.
 */


import React, { useEffect, useState, useRef, useMemo } from "react";
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import { Form, Input, Button, Select } from 'antd';
import { Table, Divider, Modal } from 'antd';
const { Option } = Select;

// 组件
function info(record) {
    console.log("info-----", record, record.values)
    Modal.info({
        title: '个人信息',
        content: (
            <div>
                {Object.values(record)}
            </div>
        ),
        onOk() { },
    });
}

const columns = [
    {
        title: 'Name',
        dataIndex: 'name',
    },
    {
        title: 'Age',
        dataIndex: 'age',
    },
    {
        title: 'Address',
        dataIndex: 'address',
    },
    {
        title: 'Action',
        dataIndex: 'action',
        key: 'name',
        render: (text, record) => <Button onClick={() => info(record)}>查看</Button >,
    },
];
const data = [
    {
        key: '1',
        name: 'John Brown',
        age: 32,
        address: 'New York No. 1 Lake Park',
    },
    {
        key: '2',
        name: 'Jim Green',
        age: 42,
        address: 'London No. 1 Lake Park',
    },
    {
        key: '3',
        name: 'Joe Black',
        age: 32,
        address: 'Sidney No. 1 Lake Park',
    },
    {
        key: '4',
        name: 'Disabled User',
        age: 99,
        address: 'Sidney No. 1 Lake Park',
    },
]; // rowSelection object indicates the need for row selection


// 弹窗组件
const MyModal = ({ chooseSet }) => {
    console.log('rerender------>Modal', typeof chooseSet)
    const [isModalVisible, setIsModalVisible] = useState(false);

    const showModal = () => {
        setIsModalVisible(true);
    };

    const handleOk = () => {
        setIsModalVisible(false);
    };

    const handleCancel = () => {
        setIsModalVisible(false);
    };

    return (
        <>
            <Button type="primary" onClick={showModal}>
                弹窗选择
            </Button>
            <Modal title="Basic Modal" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
                <Table
                    rowSelection={{
                        type: 'radio',
                        onChange: (selectedRowKeys, selectedRows) => {
                            console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', ...selectedRows);
                            chooseSet(...selectedRows) // 将选中的值设置到组件 2
                        },
                    }}
                    columns={columns}
                    dataSource={data}
                />
            </Modal>
        </>
    );
};

// 组件 1
const MyTable = ({ show, chooseSet }) => {
    console.log('rerender------>MyTable', show, typeof chooseSet)
    return (
        <div hidden={show}>
            <Divider />
            <Table
                rowSelection={{
                    type: 'radio',
                    onChange: (selectedRowKeys, selectedRows) => {
                        console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', ...selectedRows);
                        chooseSet(...selectedRows) // 将选中的值设置到组件 2
                    },
                }}
                columns={columns}
                dataSource={data}
            />
        </div>
    );
};



// 组件 2
const Demo = () => {
    const [form] = Form.useForm();
    console.log('rerender------Demo')

    // 表单之间联动,可以设置其他表单项的值
    const onGenderChange = (value) => {
        console.log('------onGenderChange', value)
        switch (value) {
            case 'male':
                return;

            case 'female':
                form.setFieldsValue({
                    note1: 'Hi, lady!', // 设置 note1 的值,也可以设置其他 note 的值
                });
                return;

            case 'other':
                form.setFieldsValue({
                    note1: 'Hi there!',
                });
                break
            default:
                console.log('no.....')
        }
    };

    // 表格默认值
    let FormDefaultValue = {
        note1: 'Hello world!',
        note2: '默认数据 1', //也可以在这里绑定 note2 的值
        note3: '默认数据 2', //也可以在这里绑定 note3 的值
        gender: '默认数据 3',
    }

    // 表格填写完毕自动执行
    const onFinish = (values) => {
        console.log(values);
    };
    // 字段修改时自动执行
    const onUpdate = (values) => {
        // form.setFieldsValue({
        //     note2: env1.name, //也可以在这里绑定 note2 的值
        //     note3: env2.name, //也可以在这里绑定 note3 的值
        // })
        console.log(values);
    };
    // 重置表格
    const onReset = () => {
        form.resetFields();
        setEnv1({ name: null })
        setEnv2({ name: null })
    };
    // 清空表格
    const onFill = () => {
        form.setFieldsValue(FormDefaultValue);
        setEnv1({ name: FormDefaultValue.note2 })
        setEnv2({ name: FormDefaultValue.note3 })
    };
    const [env1, setEnv1] = useState({}) // 感觉这种方式过渡了下,先设置到了外面的 hookstate 中,再由其他函数设置到 Form.Item的 value 上,不是很优雅
    const [env2, setEnv2] = useState({})
    const [show, setShow] = useState(true)

    useEffect(() => {
        console.log("----useEffect-----")
        // 渲染完成后设置表单的值为最新的值,避免自动检验报错
        form.setFieldsValue({
            note2: env1.name, //也可以在这里绑定 note2 的值
            note3: env2.name, //也可以在这里绑定 note3 的值
        })
    });
    return (
        <Form form={form} name="control-hooks" onValuesChange={onUpdate} onFinish={onFinish}>

            <Form.Item
                name="note1"
                label="简单组件"
                initialValue='默认初始值'
                extra="please input username." // 参数说明
                rules={[{ required: true, message: 'note1 为必须参数!' },]} // 设定为必要参数,并自定义提示
            >
                <Input />
            </Form.Item>

            <Form.Item
                name="note2" //这里的 name 和 rules 移到内部的真正提供数据的组件的外围的Form.Item中
                rules={[{ required: true, },]} // Form.Item一定要直接包裹Input或其他提供数据的组件,如果有其他元素，就重新包裹一层
                label="选项组件"
            >
                <div>
                    <Button type="primary"
                        onClick={() => {
                            setShow(!show);
                        }}
                    >
                        {show ? <>选择</> : <>隐藏</>}
                    </Button>
                    {/* 这里展示出下面组件选中的值,也是本次文件主要解决的问题,让 form,div,table 三个组件的值统一 */}
                    <label>{env1.name}</label>
                    <MyTable show={show} chooseSet={setEnv1} />
                </div>

            </Form.Item>

            <Form.Item
                name="note3"    // 这个 note3 没有报 name 不应该设置, note2这样设置会报错.因为Form.Item下应该只有唯一元素
                label="弹窗组件"
                rules={[{ required: true, },]}
            >
                <div>
                    {/* 这里展示出下面组件选中的值,也是本次文件主要解决的问题,让 form,div,table 三个组件的值统一 */}
                    <label>{env2.name}</label>
                    <MyModal chooseSet={setEnv2} />
                </div>
            </Form.Item>


            <Form.Item
                name="gender"
                label="Gender"
                rules={[{ required: true, },]}
            >
                <Select
                    placeholder="Select a option and change input text above"
                    onChange={onGenderChange}
                    allowClear
                >
                    <Option value="male">手动</Option>
                    <Option value="female">自动选择</Option>
                    <Option value="other">other</Option>
                </Select>
            </Form.Item>


            <Form.Item
                // noStyle
                shouldUpdate={(prevValues, currentValues) => prevValues.gender !== currentValues.gender}
            >
                {({ getFieldValue }) =>
                    getFieldValue('gender') === 'other' ? (
                        <Form.Item
                            name="customizeGender"
                            label="Customize Gender"
                            rules={[{ required: true, },]}
                        >
                            <Input />
                        </Form.Item>
                    ) : null
                }
            </Form.Item>
            <Form.Item >
                <Button type="primary" htmlType="submit"
                    onClick={() => {
                        form.setFieldsValue({
                            // note2: env1.name, //也可以在这里绑定 note2 的值
                            // note3: env2.name, //也可以在这里绑定 note3 的值
                        })
                    }}>
                    Submit
                </Button>
                <Button htmlType="button" onClick={onReset}>
                    Reset
                </Button>
                <Button type="link" htmlType="button" onClick={onFill}>
                    Fill form
                </Button>
            </Form.Item>
        </Form>
    );
};

export default Demo



/*
# [antd: Form.Item] `children` is array of render props cannot have `name` 这种报错,是因为Form.Item 内有多个元素的使用方式并设置了 name 属性.
https://ant.design/components/form-cn/#components-form-demo-complex-form-control
Form.Item 内有多个元素的使用方式。<Form.Item name="field" /> 只会对它的直接子元素绑定表单功能，例如直接包裹了 Input/Select。
如果控件前后还有一些文案或样式装点，或者一个表单项内有多个控件，你可以使用内嵌的 Form.Item 完成。
你可以给 Form.Item 自定义 style 进行内联布局，或者添加 noStyle 作为纯粹的无样式绑定组件（类似 3.x 中的 getFieldDecorator）。

https://ant.design/components/modal-cn/#components-modal-demo-info

https://ant.design/components/form-cn/#API


*/